package com.aaa.sso.service.impl;

import com.aaa.common.bo.User;
import com.aaa.common.util.ConstUtil;
import com.aaa.common.util.Result;
import com.aaa.common.util.ResultStatus;
import com.aaa.sso.service.AuthService;
import com.aaa.sso.service.RemoteUserService;
import com.aaa.sso.util.JwtUtils;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @ fileName:UserAuthServiceImpl
 * @ description:
 * @ author:zhz
 * @ createTime:2023/6/16 11:40
 * @ version:1.0.0
 */
@Service("uas")
public class UserAuthServiceImpl implements AuthService {

    @Resource
    private RemoteUserService remoteUserService;

    //依赖注入  spring框架封装的Redis连接模板类
    @Resource
    private RedisTemplate redisTemplate;


    @Override
    public Result auth(String userName, String password) {
        //需要根据用户名查询用户信息
        User user = remoteUserService.queryByUsername(userName);
        //再次使用密码和盐值进行加密运算
        Sha512Hash sha512Hash = new Sha512Hash(password,user.getSalt(),
                ConstUtil.CredentialsMatcher.HASH_ITERATIONS);
        //判断密码是否正确
        if(user.getPassword().equals(sha512Hash.toString())){
            Map<String, String> payload = new HashMap<>();
            payload.put("userId", user.getUserId().toString());
            payload.put("userName", user.getUserName());
           //生成token  使用jwt
            String token = userName+"-"+JwtUtils.generateToken(payload);
            //还要把生成的token存储到redis中  方便后面用来校验token
                //设置redis的key的序列化方式   使用StringRedisSerializer 方式时，存储到redis中的就是string字符串
            redisTemplate.setKeySerializer(new StringRedisSerializer());
               //先查询userName+"-"+****
            Set keys = redisTemplate.keys(userName + "-*");
                //再循环删除
            for (Object key : keys) {
                //删除
                redisTemplate.delete(key);
            }
            //redisTemplate.setValueSerializer(new StringRedisSerializer());
            //把token放入redis  把token作为key   用户对象做为值   方便后面使用token获取用户信息
            redisTemplate.opsForValue().set(token, user, 8, TimeUnit.HOURS);
            //把token返回给前端
            return new Result(ResultStatus.SUCCESS.getReturnCode(),ResultStatus.SUCCESS.getReturnMsg(),
                    token);
        }else {
            //用户名或者密码错误，返回错误json
           return new Result(ResultStatus.ERROR.getReturnCode(),
                   ResultStatus.ERROR.getReturnMsg(),"用户名或者密码错误！");
        }
    }

    @Override
    public boolean checkToken(String token) {
        //设置redis的key的序列化方式   使用StringRedisSerializer 方式时，存储到redis中的就是string字符串
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //token  =  userName+"-"+xxx.xxx.xxx
        //String[] tokenArray = token.split("-");
        String tokenSub = token.substring(token.indexOf("-") + 1);
        //tokenArray[1] =  xxx.xxx.xxx
        //根据JwtUtils判断token是否正确    再判断redis是否存在（是否过期）
        if(JwtUtils.verify(tokenSub)&&redisTemplate.hasKey(token)){
            return true;
        }
        return false;
    }


}
